package com.aplink.generic.adapter;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

import android.location.Location;
import android.text.TextUtils;
import android.widget.Filter;

import com.aplink.generic.pojo.GenericObject;

public class RadiusFilter extends Filter {
	private class RadiusGenericObject {
		float mDistance;
		GenericObject mGenericObject;

	}
	private Comparator<RadiusGenericObject> mComparator = new Comparator<RadiusFilter.RadiusGenericObject>() {

		@Override
		public int compare(RadiusGenericObject lhs, RadiusGenericObject rhs) {
			return (int) (lhs.mDistance - rhs.mDistance);
		}
	};

	private final ConfigAdapter mConfigAdapter;

	private Location mLocation;

	public RadiusFilter(Location location, final ConfigAdapter configAdapter) {
		mLocation = location;
		mConfigAdapter = configAdapter;
	}

	public Location getLocation() {
		return mLocation;
	}

	@Override
	protected FilterResults performFiltering(CharSequence constraint) {
		FilterResults filterResults = new FilterResults();
		ArrayList<RadiusGenericObject> filteredArrList = new ArrayList<RadiusGenericObject>();
		if (constraint.toString().equalsIgnoreCase("All")) {
			constraint = null;
		}
		if (TextUtils.isEmpty(constraint)) {
			for (final GenericObject genericObject : mConfigAdapter
			        .getOriginalObjects()) {
				RadiusGenericObject radiusGenericObject = new RadiusGenericObject();
				float distance = genericObject.getLocation().distanceTo(
				        mLocation);
				radiusGenericObject.mDistance = distance;
				radiusGenericObject.mGenericObject = genericObject;
				filteredArrList.add(radiusGenericObject);
			}
			filterResults.count = filteredArrList.size();
			filterResults.values = filteredArrList;
		} else {
			int radius = Integer.parseInt(constraint.toString().split(" ")[0]) * 1000;
			for (final GenericObject genericObject : mConfigAdapter
			        .getOriginalObjects()) {
				RadiusGenericObject radiusGenericObject = new RadiusGenericObject();
				float distance = genericObject.getLocation().distanceTo(
				        mLocation);
				if (distance <= radius) {
					radiusGenericObject.mDistance = distance;
					radiusGenericObject.mGenericObject = genericObject;
					filteredArrList.add(radiusGenericObject);
				}
			}
			filterResults.count = filteredArrList.size();
			filterResults.values = filteredArrList;
		}
		return filterResults;
	}

	@SuppressWarnings("unchecked")
	@Override
	protected void publishResults(final CharSequence constraint,
	        final FilterResults results) {
		ArrayList<RadiusGenericObject> listRadiusGenericObjects = (ArrayList<RadiusGenericObject>) results.values;
		Collections.sort(listRadiusGenericObjects, mComparator);
		ArrayList<GenericObject> finalResults = new ArrayList<>();
		for (RadiusGenericObject radiusGenericObject : listRadiusGenericObjects) {
			finalResults.add(radiusGenericObject.mGenericObject);
		}
		mConfigAdapter.setDisplayObjects(finalResults);
		if (finalResults.size() == mConfigAdapter.getOriginalObjects().size()) {
			mConfigAdapter.setOriginalObjects(finalResults);
		}
	}

	public void setLocation(Location location) {
		mLocation = location;
	}
}
